netty案例,netty4.1基础入门篇零《初入JavaIO之门BIO、NIO、AIO实战练习》
作者:付政委
祝努力的你,所求皆如愿 所行化坦途
微信公众号:bugstack虫洞栈 | 1k+关注
跟着案例学Netty,Netty4.x案例从简单入门到应用实战,全篇35章节优秀案例+源码分析[基础篇(13)、中级篇(12)、高级篇(3章+)、源码分析篇(6)],以上章节全部完成并不断持续更新中,欢迎关注学习&下载专题源码
前言介绍
在Java中,提供了一些关于使用IO的API,可以供开发者来读写外部数据和文件,我们称这些API为Java IO。IO是Java中比较重要知识点,且比较难学习的知识点。并且随着Java的发展为提供更好的数据传输性能,目前有三种IO共存;分别是BIO、NIO和AIO。
Java BIO[Blocking I/O] | 同步阻塞I/O模式
BIO 全称Block-IO 是一种同步且阻塞的通信模式。是一个比较传统的通信方式,模式简单,使用方便。但并发处理能力低,通信耗时,依赖网速。
Java NIO[New I/O] | 同步非阻塞模式
Java NIO,全程 Non-Block IO ,是Java SE 1.4版以后,针对网络传输效能优化的新功能。是一种非阻塞同步的通信模式。
NIO 与原来的 I/O 有同样的作用和目的, 他们之间最重要的区别是数据打包和传输的方式。原来的 I/O 以流的方式处理数据,而 NIO 以块的方式处理数据。
面向流的 I/O 系统一次一个字节地处理数据。一个输入流产生一个字节的数据,一个输出流消费一个字节的数据。
面向块的 I/O 系统以块的形式处理数据。每一个操作都在一步中产生或者消费一个数据块。按块处理数据比按(流式的)字节处理数据要快得多。但是面向块的 I/O - 缺少一些面向流的 I/O 所具有的优雅性和简单性。
Java AIO[Asynchronous I/O] | 异步非阻塞I/O模型
Java AIO,全程 Asynchronous IO,是异步非阻塞的IO。是一种非阻塞异步的通信模式。在NIO的基础上引入了新的异步通道的概念,并提供了异步文件通道和异步套接字通道的实现。
如下我们将分别对三种IO进行案例演示,通过对三种的IO的认知来方便学习后续的Netty知识。
开发环境
1、jdk1.8【jdk1.7及以上,AIO需要1.7】
2、NetAssist 网络调试助手[获取:关注公众号:bugstack虫洞栈 | 回复;NetAssist+邮箱]
代码示例
1itstack-demo-netty-1-00
2└── src
3 ├── main
4 │ └── java
5 │ └── org.itstack.demo.netty
6 │ ├── aio
7 │ │ ├── client
8 │ │ │ ├── AioClient.java
9 │ │ │ └── AioClientHandler.java
10 │ │ ├── server
11 │ │ │ ├── AioServer.java
12 │ │ │ ├── AioServerChannelInitializer.java
13 │ │ │ └── AioServerHandler.java
14 │ │ ├── ChannelAdapter.java
15 │ │ ├── ChannelHandler.java
16 │ │ └── ChannelInitializer.java
17 │ ├── bio
18 │ │ ├── client
19 │ │ │ ├── BioClient.java
20 │ │ │ └── BioClientHandler.java
21 │ │ ├── server
22 │ │ │ ├── BioServer.java
23 │ │ │ └── BioServerHandler.java
24 │ │ ├── ChannelAdapter.java
25 │ │ └── ChannelHandler.java
26 │ └── nio
27 │ ├── client
28 │ │ ├── NioClient.java
29 │ │ └── NioClientHandler.java
30 │ ├── server
31 │ │ ├── NioServer.java
32 │ │ └── NioServerHandler.java
33 │ ├── ChannelAdapter.java
34 │ └── ChannelHandler.java
35 └── test
36 └── java
37 └── org.itstack.demo.test
38 └── ApiTest.java
重点代码块讲解,完整代码,关注公众号:bugstack虫洞栈 | 回复Netty源码获取
AIO案例代码
aio/client/AioClient.java | 客户端
1/**
2 * 微信公众号:bugstack虫洞栈 | 专注原创技术专题案例,以最易学习编程的方式分享知识,让萌新、小白、大牛都能有所收获。目前已完成的专题有;Netty4.x从入门到实战、用Java实现JVM、基于JavaAgent的全链路监控等,其他更多专题还在排兵布阵中。
3 * 论坛:http://bugstack.cn
4 * Create by 付政委 on @2019
5 */
6public class AioClient {
7
8 public static void main(String[] args) throws Exception {
9 AsynchronousSocketChannel socketChannel = AsynchronousSocketChannel.open();
10 Future<Void> future = socketChannel.connect(new InetSocketAddress("192.168.1.116", 7397));
11 System.out.println("itstack-demo-netty client start done. {关注公众号:bugstack虫洞栈 | 欢迎关注&获取源码}");
12 future.get();
13 socketChannel.read(ByteBuffer.allocate(1024), null, new AioClientHandler(socketChannel, Charset.forName("GBK")));
14 Thread.sleep(100000);
15 }
16
17}
aio/client/AioClientHandler.java | 客户端消息处理器
1**
2 * 微信公众号:bugstack虫洞栈 | 专注原创技术专题案例,以最易学习编程的方式分享知识,让萌新、小白、大牛都能有所收获。目前已完成的专题有;Netty4.x从入门到实战、用Java实现JVM、基于JavaAgent的全链路监控等,其他更多专题还在排兵布阵中。
3 * 论坛:http://bugstack.cn
4 * Create by 付政委 on @2019
5 */
6public class AioClientHandler extends ChannelAdapter {
7
8 public AioClientHandler(AsynchronousSocketChannel channel, Charset charset) {
9 super(channel, charset);
10 }
11
12
13 public void channelActive(ChannelHandler ctx) {
14 try {
15 System.out.println("微信公众号:bugstack虫洞栈 | 链接报告信息:" + ctx.channel().getRemoteAddress());
16 //通知客户端链接建立成功
17 } catch (IOException e) {
18 e.printStackTrace();
19 }
20 }
21
22
23 public void channelInactive(ChannelHandler ctx) {
24 }
25
26
27 public void channelRead(ChannelHandler ctx, Object msg) {
28 System.out.println("微信公众号:bugstack虫洞栈 | 服务端收到:" + new Date() + " " + msg + "\r\n");
29 ctx.writeAndFlush("客户端信息处理Success!\r\n");
30 }
31
32}
aio/server/AioServer.java | 服务端
1/**
2 * 微信公众号:bugstack虫洞栈 | 专注原创技术专题案例,以最易学习编程的方式分享知识,让萌新、小白、大牛都能有所收获。目前已完成的专题有;Netty4.x从入门到实战、用Java实现JVM、基于JavaAgent的全链路监控等,其他更多专题还在排兵布阵中。
3 * 论坛:http://bugstack.cn
4 * Create by 付政委 on @2019
5 */
6public class AioServer extends Thread {
7
8 private AsynchronousServerSocketChannel serverSocketChannel;
9
10
11 public void run() {
12 try {
13 serverSocketChannel = AsynchronousServerSocketChannel.open(AsynchronousChannelGroup.withCachedThreadPool(Executors.newCachedThreadPool(), 10));
14 serverSocketChannel.bind(new InetSocketAddress(7397));
15 System.out.println("itstack-demo-netty server start done. {关注公众号:bugstack虫洞栈 | 欢迎关注&获取源码}");
16 // 等待
17 CountDownLatch latch = new CountDownLatch(1);
18 serverSocketChannel.accept(this, new AioServerChannelInitializer());
19 latch.await();
20 } catch (Exception e) {
21 e.printStackTrace();
22 }
23 }
24
25 public AsynchronousServerSocketChannel serverSocketChannel() {
26 return serverSocketChannel;
27 }
28
29 public static void main(String[] args) {
30 new AioServer().start();
31 }
32
33}
aio/server/AioServerChannelInitializer.java | 初始化
1/**
2 * 微信公众号:bugstack虫洞栈 | 专注原创技术专题案例,以最易学习编程的方式分享知识,让萌新、小白、大牛都能有所收获。目前已完成的专题有;Netty4.x从入门到实战、用Java实现JVM、基于JavaAgent的全链路监控等,其他更多专题还在排兵布阵中。
3 * 论坛:http://bugstack.cn
4 * Create by 付政委 on @2019
5 */
6public class AioServerChannelInitializer extends ChannelInitializer {
7
8
9 protected void initChannel(AsynchronousSocketChannel channel) throws Exception {
10 channel.read(ByteBuffer.allocate(1024), 10, TimeUnit.SECONDS, null, new AioServerHandler(channel, Charset.forName("GBK")));
11 }
12
13}
aio/server/AioServerHandler.java | 处理消息
1/**
2 * 微信公众号:bugstack虫洞栈 | 专注原创技术专题案例,以最易学习编程的方式分享知识,让萌新、小白、大牛都能有所收获。目前已完成的专题有;Netty4.x从入门到实战、用Java实现JVM、基于JavaAgent的全链路监控等,其他更多专题还在排兵布阵中。
3 * 论坛:http://bugstack.cn
4 * Create by 付政委 on @2019
5 */
6public class AioServerHandler extends ChannelAdapter {
7
8 public AioServerHandler(AsynchronousSocketChannel channel, Charset charset) {
9 super(channel, charset);
10 }
11
12
13 public void channelActive(ChannelHandler ctx) {
14 try {
15 System.out.println("微信公众号:bugstack虫洞栈 | 链接报告信息:" + ctx.channel().getRemoteAddress());
16 //通知客户端链接建立成功
17 ctx.writeAndFlush("微信公众号:bugstack虫洞栈 | 通知服务端链接建立成功" + " " + new Date() + " " + ctx.channel().getRemoteAddress() + "\r\n");
18 } catch (IOException e) {
19 e.printStackTrace();
20 }
21 }
22
23
24 public void channelInactive(ChannelHandler ctx) {
25 }
26
27
28 public void channelRead(ChannelHandler ctx, Object msg) {
29 System.out.println("微信公众号:bugstack虫洞栈 | 服务端收到:" + new Date() + " " + msg + "\r\n");
30 ctx.writeAndFlush("服务端信息处理Success!\r\n");
31 }
32
33}
aio/ChannelAdapter.java | Channle适配器模仿Netty
1/**
2 * 消息处理器
3 * 微信公众号:bugstack虫洞栈 | 专注原创技术专题案例,以最易学习编程的方式分享知识,让萌新、小白、大牛都能有所收获。目前已完成的专题有;Netty4.x从入门到实战、用Java实现JVM、基于JavaAgent的全链路监控等,其他更多专题还在排兵布阵中。
4 * 论坛:http://bugstack.cn
5 * Create by 付政委 on @2019
6 */
7public abstract class ChannelAdapter implements CompletionHandler<Integer, Object> {
8
9 private AsynchronousSocketChannel channel;
10 private Charset charset;
11
12 public ChannelAdapter(AsynchronousSocketChannel channel, Charset charset) {
13 this.channel = channel;
14 this.charset = charset;
15 if (channel.isOpen()) {
16 channelActive(new ChannelHandler(channel, charset));
17 }
18 }
19
20
21 public void completed(Integer result, Object attachment) {
22 try {
23 final ByteBuffer buffer = ByteBuffer.allocate(1024);
24 final long timeout = 60 * 60L;
25 channel.read(buffer, timeout, TimeUnit.SECONDS, null, new CompletionHandler<Integer, Object>() {
26
27 public void completed(Integer result, Object attachment) {
28 if (result == -1) {
29 try {
30 channelInactive(new ChannelHandler(channel, charset));
31 channel.close();
32 } catch (IOException e) {
33 e.printStackTrace();
34 }
35 return;
36 }
37 buffer.flip();
38 channelRead(new ChannelHandler(channel, charset), charset.decode(buffer));
39 buffer.clear();
40 channel.read(buffer, timeout, TimeUnit.SECONDS, null, this);
41 }
42
43
44 public void failed(Throwable exc, Object attachment) {
45 exc.printStackTrace();
46 }
47 });
48 } catch (Exception e) {
49 e.printStackTrace();
50 }
51 }
52
53
54
55 public void failed(Throwable exc, Object attachment) {
56 exc.getStackTrace();
57 }
58
59 public abstract void channelActive(ChannelHandler ctx);
60
61 public abstract void channelInactive(ChannelHandler ctx);
62
63 // 读取消息抽象类
64 public abstract void channelRead(ChannelHandler ctx, Object msg);
65
66}
AIO案例演示 | 服务端测试
启动AioServer
1itstack-demo-netty aio server start done. {关注公众号:bugstack虫洞栈 | 欢迎关注&获取源码}
2微信公众号:bugstack虫洞栈 | 链接报告信息:/192.168.1.116:57208
3微信公众号:bugstack虫洞栈 | 服务端收到:Sun Oct 06 18:19:50 CST 2019 hi aio server! helloworld
4
5微信公众号:bugstack虫洞栈 | 服务端收到:Sun Oct 06 18:19:51 CST 2019 hi aio server! helloworld
6
7微信公众号:bugstack虫洞栈 | 服务端收到:Sun Oct 06 18:19:51 CST 2019 hi aio server! helloworld
8
9微信公众号:bugstack虫洞栈 | 服务端收到:Sun Oct 06 18:19:52 CST 2019 hi aio server! helloworld
10
11
12Process finished with exit code -1
BIO案例代码
bio/client/BioClient.java | 客户端
1/**
2 * 微信公众号:bugstack虫洞栈 | 专注原创技术专题案例,以最易学习编程的方式分享知识,让萌新、小白、大牛都能有所收获。目前已完成的专题有;Netty4.x从入门到实战、用Java实现JVM、基于JavaAgent的全链路监控等,其他更多专题还在排兵布阵中。
3 * 论坛:http://bugstack.cn
4 * Create by 付政委 on @2019
5 */
6public class BioClient {
7
8 public static void main(String[] args) {
9 try {
10 Socket socket = new Socket("192.168.1.116", 7397);
11 System.out.println("itstack-demo-netty client start done. {关注公众号:bugstack虫洞栈 | 欢迎关注&获取源码}");
12 BioClientHandler bioClientHandler = new BioClientHandler(socket, Charset.forName("utf-8"));
13 bioClientHandler.start();
14 } catch (IOException e) {
15 e.printStackTrace();
16 }
17 }
18
19}
bio/client/BioClientHandler.java | 消息处理器
1/**
2 * 微信公众号:bugstack虫洞栈 | 专注原创技术专题案例,以最易学习编程的方式分享知识,让萌新、小白、大牛都能有所收获。目前已完成的专题有;Netty4.x从入门到实战、用Java实现JVM、基于JavaAgent的全链路监控等,其他更多专题还在排兵布阵中。
3 * 论坛:http://bugstack.cn
4 * Create by 付政委 on @2019
5 */
6public class BioClientHandler extends ChannelAdapter {
7
8 public BioClientHandler(Socket socket, Charset charset) {
9 super(socket, charset);
10 }
11
12
13 public void channelActive(ChannelHandler ctx) {
14 System.out.println("链接报告LocalAddress:" + ctx.socket().getLocalAddress());
15 ctx.writeAndFlush("hi! 我是bugstack虫洞栈 BioClient to msg for you \r\n");
16 }
17
18
19 public void channelRead(ChannelHandler ctx, Object msg) {
20 System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " 接收到消息:" + msg);
21 ctx.writeAndFlush("hi 我已经收到你的消息Success!\r\n");
22 }
23
24}
bio/server/BioServer.java | 服务端
1/**
2 * 博客:http://itstack.org
3 * 论坛:http://bugstack.cn
4 * 公众号:bugstack虫洞栈 {获取学习源码}
5 * Create by fuzhengwei on 2019/9/30
6 */
7public class BioServer extends Thread {
8
9 private ServerSocket serverSocket = null;
10
11 public static void main(String[] args) {
12 BioServer bioServer = new BioServer();
13 bioServer.start();
14 }
15
16
17 public void run() {
18 try {
19 serverSocket = new ServerSocket();
20 serverSocket.bind(new InetSocketAddress(7397));
21 System.out.println("itstack-demo-netty server start done. {关注公众号:bugstack虫洞栈 | 欢迎关注&获取源码}");
22 while (true) {
23 Socket socket = serverSocket.accept();
24 BioServerHandler handler = new BioServerHandler(socket, Charset.forName("utf-8"));
25 handler.start();
26 }
27 } catch (IOException e) {
28 e.printStackTrace();
29 }
30 }
31}
bio/server/BioServerHandler.java | 消息处理器
1/**
2 * 微信公众号:bugstack虫洞栈 | 专注原创技术专题案例,以最易学习编程的方式分享知识,让萌新、小白、大牛都能有所收获。目前已完成的专题有;Netty4.x从入门到实战、用Java实现JVM、基于JavaAgent的全链路监控等,其他更多专题还在排兵布阵中。
3 * 论坛:http://bugstack.cn
4 * Create by 付政委 on @2019
5 */
6public class BioServerHandler extends ChannelAdapter {
7
8 public BioServerHandler(Socket socket, Charset charset) {
9 super(socket, charset);
10 }
11
12
13 public void channelActive(ChannelHandler ctx) {
14 System.out.println("链接报告LocalAddress:" + ctx.socket().getLocalAddress());
15 ctx.writeAndFlush("hi! 我是bugstack虫洞栈 BioServer to msg for you \r\n");
16 }
17
18
19 public void channelRead(ChannelHandler ctx, Object msg) {
20 System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " 接收到消息:" + msg);
21 ctx.writeAndFlush("hi 我已经收到你的消息Success!\r\n");
22 }
23
24}
bio/ChannelAdapter.java | 适配器
1/**
2 * 微信公众号:bugstack虫洞栈 | 专注原创技术专题案例,以最易学习编程的方式分享知识,让萌新、小白、大牛都能有所收获。目前已完成的专题有;Netty4.x从入门到实战、用Java实现JVM、基于JavaAgent的全链路监控等,其他更多专题还在排兵布阵中。
3 * 论坛:http://bugstack.cn
4 * Create by 付政委 on @2019
5 */
6public abstract class ChannelAdapter extends Thread {
7
8 private Socket socket;
9 private ChannelHandler channelHandler;
10 private Charset charset;
11
12 public ChannelAdapter(Socket socket, Charset charset) {
13 this.socket = socket;
14 while (!socket.isConnected()) {
15 break;
16 }
17 channelHandler = new ChannelHandler(this.socket, charset);
18 channelActive(channelHandler);
19 }
20
21
22 public void run() {
23 try {
24 BufferedReader input = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
25 String str = null;
26 while ((str = input.readLine()) != null) {
27 channelRead(channelHandler, str);
28 }
29 } catch (IOException e) {
30 e.printStackTrace();
31 }
32 }
33
34 // 链接通知抽象类
35 public abstract void channelActive(ChannelHandler ctx);
36
37 // 读取消息抽象类
38 public abstract void channelRead(ChannelHandler ctx, Object msg);
39
40}
BIO案例测试
启动BioServer
1itstack-demo-netty bio server start done. {关注公众号:bugstack虫洞栈 | 欢迎关注&获取源码}
2链接报告LocalAddress:/192.168.1.116
32019-10-06 18:28:17 接收到消息:hi bio server! helloworld {结尾是换行符}
42019-10-06 18:28:17 接收到消息:hi bio server! helloworld {结尾是换行符}
52019-10-06 18:28:18 接收到消息:hi bio server! helloworld {结尾是换行符}
62019-10-06 18:28:18 接收到消息:hi bio server! helloworld {结尾是换行符}
72019-10-06 18:28:19 接收到消息:hi bio server! helloworld {结尾是换行符}
82019-10-06 18:28:19 接收到消息:hi bio server! helloworld {结尾是换行符}
9
10Process finished with exit code -1
NIO案例代码
nio/client/NioClient.java | 客户端
1/**
2 * 微信公众号:bugstack虫洞栈 | 专注原创技术专题案例,以最易学习编程的方式分享知识,让萌新、小白、大牛都能有所收获。目前已完成的专题有;Netty4.x从入门到实战、用Java实现JVM、基于JavaAgent的全链路监控等,其他更多专题还在排兵布阵中。
3 * 论坛:http://bugstack.cn
4 * Create by 付政委 on @2019
5 */
6public class NioClient {
7
8 public static void main(String[] args) throws IOException {
9 Selector selector = Selector.open();
10 SocketChannel socketChannel = SocketChannel.open();
11 socketChannel.configureBlocking(false);
12
13 boolean isConnect = socketChannel.connect(new InetSocketAddress("192.168.1.116", 7397));
14 if (isConnect) {
15 socketChannel.register(selector, SelectionKey.OP_READ);
16 } else {
17 socketChannel.register(selector, SelectionKey.OP_CONNECT);
18 }
19 System.out.println("itstack-demo-netty client start done. {关注公众号:bugstack虫洞栈 | 欢迎关注&获取源码}");
20 new NioClientHandler(selector, Charset.forName("GBK")).start();
21 }
22
23}
nio/client/NioClientHandler.java | 消息处理器
1/**
2 * 微信公众号:bugstack虫洞栈 | 专注原创技术专题案例,以最易学习编程的方式分享知识,让萌新、小白、大牛都能有所收获。目前已完成的专题有;Netty4.x从入门到实战、用Java实现JVM、基于JavaAgent的全链路监控等,其他更多专题还在排兵布阵中。
3 * 论坛:http://bugstack.cn
4 * Create by 付政委 on @2019
5 */
6public class NioClientHandler extends ChannelAdapter {
7
8 public NioClientHandler(Selector selector, Charset charset) {
9 super(selector, charset);
10 }
11
12
13 public void channelActive(ChannelHandler ctx) {
14 try {
15 System.out.println("链接报告LocalAddress:" + ctx.channel().getLocalAddress());
16 ctx.writeAndFlush("hi! 我是bugstack虫洞栈 BioClient to msg for you \r\n");
17 } catch (IOException e) {
18 e.printStackTrace();
19 }
20 }
21
22
23 public void channelRead(ChannelHandler ctx, Object msg) {
24 System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " 接收到消息:" + msg);
25 ctx.writeAndFlush("hi 我已经收到你的消息Success!\r\n");
26 }
27
28}
nio/server/NioServer.java | 服务端
1**
2 * 微信公众号:bugstack虫洞栈 | 专注原创技术专题案例,以最易学习编程的方式分享知识,让萌新、小白、大牛都能有所收获。目前已完成的专题有;Netty4.x从入门到实战、用Java实现JVM、基于JavaAgent的全链路监控等,其他更多专题还在排兵布阵中。
3 * 论坛:http://bugstack.cn
4 * Create by 付政委 on @2019
5 */
6public class NioServer {
7
8 private Selector selector;
9 private ServerSocketChannel socketChannel;
10
11 public static void main(String[] args) throws IOException {
12 new NioServer().bind(7397);
13 }
14
15 public void bind(int port) {
16 try {
17 selector = Selector.open();
18 socketChannel = ServerSocketChannel.open();
19 socketChannel.configureBlocking(false);
20 socketChannel.socket().bind(new InetSocketAddress(port), 1024);
21 socketChannel.register(selector, SelectionKey.OP_ACCEPT);
22 System.out.println("itstack-demo-netty server start done. {关注公众号:bugstack虫洞栈 | 欢迎关注&获取源码}");
23 new NioServerHandler(selector, Charset.forName("utf-8")).start();
24 } catch (IOException e) {
25 e.printStackTrace();
26 }
27 }
28
29}
nio/server/NioServerHandler.java | 消息处理器
1/**
2 * 微信公众号:bugstack虫洞栈 | 专注原创技术专题案例,以最易学习编程的方式分享知识,让萌新、小白、大牛都能有所收获。目前已完成的专题有;Netty4.x从入门到实战、用Java实现JVM、基于JavaAgent的全链路监控等,其他更多专题还在排兵布阵中。
3 * 论坛:http://bugstack.cn
4 * Create by 付政委 on @2019
5 */
6public class NioServerHandler extends ChannelAdapter {
7
8 public NioServerHandler(Selector selector, Charset charset) {
9 super(selector, charset);
10 }
11
12
13 public void channelActive(ChannelHandler ctx) {
14 try {
15 System.out.println("链接报告LocalAddress:" + ctx.channel().getLocalAddress());
16 ctx.writeAndFlush("hi! 我是bugstack虫洞栈 BioServer to msg for you \r\n");
17 } catch (IOException e) {
18 e.printStackTrace();
19 }
20 }
21
22
23 public void channelRead(ChannelHandler ctx, Object msg) {
24 System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " 接收到消息:" + msg);
25 ctx.writeAndFlush("hi 我已经收到你的消息Success!\r\n");
26 }
27
28}
nio/ChannelAdapter.java | 适配器
1/**
2 * 微信公众号:bugstack虫洞栈 | 专注原创技术专题案例,以最易学习编程的方式分享知识,让萌新、小白、大牛都能有所收获。目前已完成的专题有;Netty4.x从入门到实战、用Java实现JVM、基于JavaAgent的全链路监控等,其他更多专题还在排兵布阵中。
3 * 论坛:http://bugstack.cn
4 * Create by 付政委 on @2019
5 */
6public abstract class ChannelAdapter extends Thread {
7
8 private Selector selector;
9
10 private ChannelHandler channelHandler;
11 private Charset charset;
12
13 public ChannelAdapter(Selector selector, Charset charset) {
14 this.selector = selector;
15 this.charset = charset;
16 }
17
18
19 public void run() {
20 while (true) {
21 try {
22 selector.select(1000); //Selects a set of keys whose corresponding channels are ready for I/O
23 Set<SelectionKey> selectedKeys = selector.selectedKeys();
24 Iterator<SelectionKey> it = selectedKeys.iterator();
25 SelectionKey key = null;
26 while (it.hasNext()) {
27 key = it.next();
28 it.remove();
29 handleInput(key);
30 }
31 } catch (Exception ignore) {
32 }
33 }
34 }
35
36 private void handleInput(SelectionKey key) throws IOException {
37 if (!key.isValid()) return;
38
39 // 客户端SocketChannel
40 Class<?> superclass = key.channel().getClass().getSuperclass();
41 if (superclass == SocketChannel.class){
42 SocketChannel socketChannel = (SocketChannel) key.channel();
43 if (key.isConnectable()) {
44 if (socketChannel.finishConnect()) {
45 channelHandler = new ChannelHandler(socketChannel, charset);
46 channelActive(channelHandler);
47 socketChannel.register(selector, SelectionKey.OP_READ);
48 } else {
49 System.exit(1);
50 }
51 }
52 }
53
54 // 服务端ServerSocketChannel
55 if (superclass == ServerSocketChannel.class){
56 if (key.isAcceptable()) {
57 ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
58 SocketChannel socketChannel = serverSocketChannel.accept();
59 socketChannel.configureBlocking(false);
60 socketChannel.register(selector, SelectionKey.OP_READ);
61
62 channelHandler = new ChannelHandler(socketChannel, charset);
63 channelActive(channelHandler);
64 }
65 }
66
67 if (key.isReadable()) {
68 SocketChannel socketChannel = (SocketChannel) key.channel();
69 ByteBuffer readBuffer = ByteBuffer.allocate(1024);
70 int readBytes = socketChannel.read(readBuffer);
71 if (readBytes > 0) {
72 readBuffer.flip();
73 byte[] bytes = new byte[readBuffer.remaining()];
74 readBuffer.get(bytes);
75 channelRead(channelHandler, new String(bytes, charset));
76 } else if (readBytes < 0) {
77 key.cancel();
78 socketChannel.close();
79 }
80 }
81 }
82
83 // 链接通知抽象类
84 public abstract void channelActive(ChannelHandler ctx);
85
86 // 读取消息抽象类
87 public abstract void channelRead(ChannelHandler ctx, Object msg);
88
89}
NIO案例测试
启动NioServer
1itstack-demo-netty nio server start done. {关注公众号:bugstack虫洞栈 | 欢迎关注&获取源码}
2链接报告LocalAddress:/192.168.1.116:7397
32019-10-06 18:33:32 接收到消息:hi bio server! helloworld {结尾无换行符}
42019-10-06 18:33:32 接收到消息:hi bio server! helloworld {结尾无换行符}
52019-10-06 18:33:32 接收到消息:hi bio server! helloworld {结尾无换行符}
62019-10-06 18:33:33 接收到消息:hi bio server! helloworld {结尾无换行符}
72019-10-06 18:33:33 接收到消息:hi bio server! helloworld {结尾无换行符}
8
9Process finished with exit code -1
《Netty4.x专题案例》👇点下<在看>